package net.guruqu.rvoView;

import java.util.LinkedList;

import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.Line;
import com.jme.scene.Node;
import com.jme.scene.Point;
import com.jme.scene.Spatial.LightCombineMode;
import com.jme.scene.Spatial.TextureCombineMode;
import com.jme.scene.state.BlendState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;

public class AgentGroup {
	LinkedList<MapAgent> agents;
	Node renderNode;
	ColorRGBA agentColor;
	ColorRGBA goalColor;
	ColorRGBA lineColor;
	int agentPointSize;

	public AgentGroup() {
		agents = new LinkedList<MapAgent>();
	}

	public void clear() {
		agents.clear();
		updateNode();
	}

	public LinkedList<MapAgent> getAgents() {
		return agents;
	}

	public Node getRenderNode() {
		if (renderNode == null) {
			renderNode = new Node("Agent Group");
			agentColor = new ColorRGBA(1, 1, 0, 0.8f);
			goalColor = new ColorRGBA(0.8f, 1, 0.2f, 0.8f);
			lineColor = new ColorRGBA(0.8f, 0, 0f, 0.4f);
			agentPointSize = 20;

			renderNode.setTextureCombineMode(TextureCombineMode.Off);
			renderNode.setLightCombineMode(LightCombineMode.Off);

			ZBufferState rs = DisplaySystem.getDisplaySystem().getRenderer()
					.createZBufferState();
			rs.setFunction(ZBufferState.TestFunction.Always);
			rs.setWritable(false);
			renderNode.setRenderState(rs);

			BlendState bs = DisplaySystem.getDisplaySystem().getRenderer()
					.createBlendState();
			bs.setEnabled(true);
			bs.setBlendEnabled(true);
			renderNode.setRenderState(bs);

			LightState lightState = DisplaySystem.getDisplaySystem()
					.getRenderer().createLightState();
			lightState.setEnabled(true);
			renderNode.setRenderState(lightState);

			// TextureState state =
			// DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
			// state.setEnabled(false);
			// state.clearTextures();
			// renderNode.setRenderState(state);
			renderNode.setRenderQueueMode(Renderer.QUEUE_SKIP);
			renderNode.updateRenderState();
		}
		return renderNode;
	}

	public MapAgent selectUnit(float x, float y, float scale) {
		for (MapAgent ma : agents) {
			if ((ma.position.x - x) * (ma.position.x - x) + (ma.position.y - y)
					* (ma.position.y - y) < agentPointSize * agentPointSize
					* scale * scale) {
				return ma;
			}
			if ((ma.goal.x - x) * (ma.goal.x - x) + (ma.goal.y - y)
					* (ma.goal.y - y) < agentPointSize * agentPointSize * scale
					* scale) {
				return ma;
			}
		}
		return null;
	}

	public static final int ST_AGENT = 0;
	public static final int ST_GOAL = 1;

	public int selectType(float x, float y, float scale) {
		for (MapAgent ma : agents) {
			if ((ma.position.x - x) * (ma.position.x - x) + (ma.position.y - y)
					* (ma.position.y - y) < agentPointSize * agentPointSize
					* scale * scale) {
				return ST_AGENT;
			}
			if ((ma.goal.x - x) * (ma.goal.x - x) + (ma.goal.y - y)
					* (ma.goal.y - y) < agentPointSize * agentPointSize * scale
					* scale) {
				return ST_GOAL;
			}
		}
		return -1;
	}

	public void updateNode() {
		if(renderNode==null)
			return;
		renderNode.detachAllChildren();
		Vector3f v3f[] = new Vector3f[agents.size()];
		Vector3f g3f[] = new Vector3f[agents.size()];
		{

			ColorRGBA c3f[] = new ColorRGBA[agents.size()];
			int i = 0;
			for (MapAgent ma : agents) {
				v3f[i] = new Vector3f(ma.position.x, 0, ma.position.y);
				c3f[i] = agentColor;
				i++;
			}
			Point point = new Point("Agent Position Rneder", v3f, null, c3f,
					null);
			point.setPointSize(agentPointSize);
			point.setAntialiased(true);
			renderNode.attachChild(point);
		}
		{
			ColorRGBA c3f[] = new ColorRGBA[agents.size()];
			int i = 0;
			for (MapAgent ma : agents) {
				g3f[i] = new Vector3f(ma.goal.x, 0, ma.goal.y);
				c3f[i] = goalColor;
				i++;
			}
			Point point = new Point("Agent Goal Rneder", g3f, null, c3f, null);
			point.setPointSize(agentPointSize / 2);
			point.setAntialiased(false);
			renderNode.attachChild(point);
		}
		{
			Vector3f l3f[] = new Vector3f[v3f.length * 2];
			ColorRGBA c3f[] = new ColorRGBA[v3f.length * 2];
			for (int i = 0; i < l3f.length; i += 2) {
				l3f[i] = v3f[i / 2];
				l3f[i + 1] = g3f[i / 2];

				c3f[i] = lineColor;
				c3f[i + 1] = lineColor;
			}
			Line line = new Line("Connecting Lines", l3f, null, c3f, null);
			line.setLineWidth(3f);
			line.setMode(Line.Mode.Segments);
			renderNode.attachChild(line);
		}
		renderNode.updateModelBound();
	}
}
